package com.own.business.message.center.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.own.business.message.center.business.service.MessageCenterContentService;
import com.own.business.message.center.business.service.MessageCenterGroupChildService;
import com.own.business.message.center.entity.bo.MessageCenterContentBo;
import com.own.business.message.center.entity.map.MessageCenterContentMapVo;
import com.own.business.message.center.entity.po.MessageCenterContent;
import com.own.business.message.center.entity.query.MessageCenterContentQuery;
import com.own.business.message.center.entity.vo.MessageCenterContentVo;
import com.own.business.message.center.mapper.MessageCenterContentMapper;
import com.own.component.common.base.service.impl.AbstractBaseService;
import com.own.component.common.model.ItemCountModel;
import com.own.component.common.model.PageModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * MessageCenterContentServiceImpl
 *
 * @author chenxueli
 * @date 2023-11-13 14:39:27
 */
@Slf4j
@Service
public class MessageCenterContentServiceImpl extends AbstractBaseService<
        MessageCenterContent,
        MessageCenterContentBo,
        MessageCenterContentVo,
        MessageCenterContentMapVo,
        MessageCenterContentQuery,
        MessageCenterContentMapper
        > implements MessageCenterContentService {

    @Resource
    private MessageCenterContentMapper messageCenterContentMapper;
    @Resource
    private MessageCenterGroupChildService messageCenterGroupChildService;

    /**
     * 设置已读
     *
     * @param userId    用户id
     * @param messageId 消息id
     */
    @Override
    public void read(Long userId, Long messageId) {
        var po = getPoById(messageId, false);
        if (po == null || po.getIsRead() == 1 || Objects.equals(userId, po.getFkReceiveId())) {
            return;
        }
        po.setIsRead(0);
        po.setReadTime(LocalDateTime.now());
        messageCenterContentMapper.updateById(po);
    }

    /**
     * 一键已读
     *
     * @param userId 用户id
     */
    @Override
    public void batchRead(Long userId) {
        var wrapper = new LambdaUpdateWrapper<MessageCenterContent>()
                .eq(MessageCenterContent::getFkReceiveId, userId)
                .eq(MessageCenterContent::getIsRead, 0)
                .set(MessageCenterContent::getIsRead, 1)
                .set(MessageCenterContent::getReadTime, LocalDateTime.now());
        messageCenterContentMapper.update(null, wrapper);
    }

    /**
     * 一键已读
     *
     * @param userId   用户id
     * @param groupKey 分组key
     */
    @Override
    public void batchRead(Long userId, String groupKey) {
        // 查询当前分组的messageKey
        var messageKeyList = messageCenterGroupChildService.listMessageKeyByGroupKey(groupKey);
        if (messageKeyList.isEmpty()) {
            return;
        }
        var wrapper = new LambdaUpdateWrapper<MessageCenterContent>()
                .eq(MessageCenterContent::getFkReceiveId, userId)
                .in(MessageCenterContent::getMessageKey, messageKeyList)
                .set(MessageCenterContent::getIsRead, 1)
                .set(MessageCenterContent::getReadTime, LocalDateTime.now());
        messageCenterContentMapper.update(null, wrapper);
    }

    /**
     * 未读消息数
     *
     * @param userId 用户id
     * @return 未读消息数
     */
    @Override
    public Long countUnread(Long userId) {
        var wrapper = new LambdaUpdateWrapper<MessageCenterContent>()
                .eq(MessageCenterContent::getFkReceiveId, userId)
                .eq(MessageCenterContent::getIsRead, 0);
        return messageCenterContentMapper.selectCount(wrapper);
    }

    /**
     * 分组查询未读数量（messageKey）
     *
     * @param userId 用户id
     * @return 未读数量
     */
    @Override
    public Map<String, Integer> mapCountUnreadByUserIdForMessageKey(Long userId) {
        var list = messageCenterContentMapper.mapCountUnreadByUserIdForMessageKey(userId);
        return list.stream().collect(Collectors.toMap(ItemCountModel::getName, ItemCountModel::getCount));
    }

    /**
     * 分组查询未读数量（groupKey）
     *
     * @param userId 用户id
     * @return 未读数量
     */
    @Override
    public Map<String, Integer> mapCountUnreadByUserIdForGroupKey(Long userId) {
        var messageKeyMap = mapCountUnreadByUserIdForMessageKey(userId);
        // 获取所有的key，查询这些key的groupKey
        var map = messageCenterGroupChildService.mapGroupKeyListByMessageKeyList(messageKeyMap.keySet());
        // 解析数据
        return map.entrySet().stream().map(entry -> {
            var messageKeyList = entry.getValue();
            // 获取到总数
            var count = messageKeyList.stream().map(messageKey -> messageKeyMap.getOrDefault(messageKey, 0)).reduce(0, Integer::sum);
            return new ItemCountModel(entry.getKey(), count);
        }).collect(Collectors.toMap(ItemCountModel::getName, ItemCountModel::getCount));
    }

    /**
     * 查询最新的消息（messageKey）
     *
     * @param userId 用户id
     * @return 最新的消息
     */
    @Override
    public Map<String, MessageCenterContentMapVo> mapLatestMessageByUserIdForMessageKey(Long userId) {
        var list = messageCenterContentMapper.mapLatestMessageByUserIdForMessageKey(userId);
        return list.stream().collect(Collectors.toMap(MessageCenterContent::getMessageKey, MessageCenterContentMapVo::new));
    }

    /**
     * 查询最新的消息（groupKey）
     *
     * @param userId 用户id
     * @return 最新的消息
     */
    @Override
    public Map<String, MessageCenterContentMapVo> mapLatestMessageByUserIdForGroupKey(Long userId) {
        var list = messageCenterContentMapper.mapLatestMessageByUserIdForMessageKey(userId);
        var map = list.stream().collect(Collectors.toMap(MessageCenterContent::getMessageKey, Function.identity(), (v1, v2) -> v1.getId() > v2.getId() ? v1 : v2));
        // 解析数据
        return messageCenterGroupChildService
                .mapGroupKeyListByMessageKeyList(map.keySet())
                .entrySet()
                .stream()
                .map(item -> {
                    // 查询最新的信息
                    return item.getValue().stream().map(map::get)
                            .peek(temp -> temp.setGroupKey(item.getKey()))
                            .max(Comparator.comparing(MessageCenterContent::getGmtCreate))
                            .orElse(null);
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(MessageCenterContent::getGroupKey, MessageCenterContentMapVo::new));
    }

    /**
     * 根据时间戳查询之后的n条信息
     *
     * @param userId    用户id
     * @param timestamp 时间戳
     * @param limit     条数
     * @return 信息
     */
    @Override
    public PageModel<MessageCenterContentVo> next(Long userId, Long timestamp, Integer limit) {
        // 时间戳转换成LocalDateTime（东八区）
        var latestTime = LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.of("+8"));
        // 设置分页
        var page = PageHelper.startPage(1, limit);
        var wrapper = lambdaQueryWrapper()
                .ge(MessageCenterContent::getGmtCreate, latestTime)
                .eq(MessageCenterContent::getFkReceiveId, userId)
                .orderByAsc(MessageCenterContent::getGmtCreate);
        var list = listByWrapper(wrapper);
        return new PageModel<>(list.stream().map(MessageCenterContentVo::new).collect(Collectors.toList()), page);
    }

}
